namespace ASPNET.StarterKit.IssueTracker.DataAccessLayer
{
    using ASPNET.StarterKit.IssueTracker.BusinessLogicLayer;
    using Microsoft.VisualBasic.CompilerServices;
    using System;
    using System.Collections;
    using System.Configuration;
    using System.Data;
    using System.Runtime.CompilerServices;
    using System.Web.UI.WebControls;

    public abstract class DataAccessLayerBaseClass
    {
        private string _connectionString;

        public abstract bool AddUserToProject(int userId, int projectId);
        public abstract bool Authenticate(string username, string password);
        public abstract bool CloneProject(int projectId, string projectName);
        public abstract int CreateNewCategory(Category newCategory);
        public abstract int CreateNewChildIssue(int primaryIssueId, int secondaryIssueId);
        public abstract int CreateNewCustomField(CustomField newCustomField);
        public abstract int CreateNewIssue(Issue newIssue);
        public abstract int CreateNewIssueAttachment(IssueAttachment newAttachment);
        public abstract int CreateNewIssueComment(IssueComment newComment);
        public abstract int CreateNewIssueNotification(IssueNotification newNotification);
        public abstract int CreateNewMilestone(Milestone newMileStone);
        public abstract int CreateNewParentIssue(int primaryIssueId, int secondaryIssueId);
        public abstract int CreateNewPriority(Priority newPriority);
        public abstract int CreateNewProject(Project newProject);
        public abstract int CreateNewRelatedIssue(int primaryIssueId, int secondaryIssueId);
        public abstract int CreateNewStatus(Status newStatus);
        public abstract int CreateNewUser(ITUser user);
        public abstract bool DeleteCategory(int categoryId);
        public abstract bool DeleteChildIssue(int primaryIssueId, int secondaryIssueId);
        public abstract bool DeleteCustomField(int customFieldId);
        public abstract bool DeleteIssue(int issueId);
        public abstract void DeleteIssueAttachment(int attachmentId);
        public abstract bool DeleteIssueNotification(int issueId, string username);
        public abstract bool DeleteMilestone(int milestoneId);
        public abstract bool DeleteParentIssue(int primaryIssueId, int secondaryIssueId);
        public abstract bool DeletePriority(int PriorityId);
        public abstract bool DeleteProject(int projectID);
        public abstract bool DeleteQuery(int queryId);
        public abstract bool DeleteRelatedIssue(int primaryIssueId, int secondaryIssueId);
        public abstract bool DeleteStatus(int statusId);
        protected CollectionBase GenerateCategoryCollectionFromReader(IDataReader returnData)
        {
            CategoryCollection mlsCollection = new CategoryCollection();
            while (returnData.Read())
            {
                Category newCategory = new Category(IntegerType.FromObject(returnData["CategoryId"]), IntegerType.FromObject(returnData["ProjectId"]), IntegerType.FromObject(returnData["ParentCategoryId"]), StringType.FromObject(returnData["CategoryName"]));
                mlsCollection.Add(newCategory);
            }
            return mlsCollection;
        }

        protected CollectionBase GenerateCustomFieldCollectionFromReader(IDataReader returnData)
        {
            CustomFieldCollection cfCollection = new CustomFieldCollection();
            while (returnData.Read())
            {
                CustomField cf = new CustomField(IntegerType.FromObject(returnData["CustomFieldId"]), IntegerType.FromObject(returnData["ProjectId"]), StringType.FromObject(returnData["CustomFieldName"]), (ValidationDataType) IntegerType.FromObject(returnData["CustomFieldDataType"]), BooleanType.FromObject(returnData["CustomFieldRequired"]), StringType.FromObject(returnData["CustomFieldValue"]));
                cfCollection.Add(cf);
            }
            return cfCollection;
        }

        protected CollectionBase GenerateIssueAttachmentCollectionFromReader(IDataReader returnData)
        {
            IssueAttachmentCollection attCollection = new IssueAttachmentCollection();
            while (returnData.Read())
            {
                IssueAttachment newAttachment = new IssueAttachment(IntegerType.FromObject(returnData["AttachmentId"]), IntegerType.FromObject(returnData["IssueId"]), StringType.FromObject(returnData["CreatorUsername"]), StringType.FromObject(returnData["CreatorDisplayName"]), DateType.FromObject(returnData["DateCreated"]), StringType.FromObject(returnData["FileName"]));
                attCollection.Add(newAttachment);
            }
            return attCollection;
        }

        protected CollectionBase GenerateIssueCollectionFromReader(IDataReader returnData)
        {
            IssueCollection issCollection = new IssueCollection();
            while (returnData.Read())
            {
                Issue newIssue = new Issue(IntegerType.FromObject(returnData["IssueId"]), IntegerType.FromObject(returnData["ProjectId"]), StringType.FromObject(returnData["IssueTitle"]), IntegerType.FromObject(returnData["IssueCategoryId"]), StringType.FromObject(returnData["CategoryName"]), IntegerType.FromObject(returnData["IssueMilestoneId"]), StringType.FromObject(returnData["MilestoneName"]), StringType.FromObject(returnData["MilestoneImageUrl"]), IntegerType.FromObject(returnData["IssuePriorityId"]), StringType.FromObject(returnData["PriorityName"]), StringType.FromObject(returnData["PriorityImageUrl"]), IntegerType.FromObject(returnData["IssueStatusId"]), StringType.FromObject(returnData["StatusName"]), StringType.FromObject(returnData["StatusImageUrl"]), StringType.FromObject(returnData["AssignedDisplayName"]), IntegerType.FromObject(returnData["IssueAssignedId"]), StringType.FromObject(returnData["OwnerDisplayName"]), IntegerType.FromObject(returnData["IssueOwnerId"]), StringType.FromObject(returnData["CreatorDisplayName"]), IntegerType.FromObject(returnData["IssueCreatorId"]), StringType.FromObject(returnData["CreatorUsername"]), DateType.FromObject(returnData["DateCreated"]));
                issCollection.Add(newIssue);
            }
            return issCollection;
        }

        protected CollectionBase GenerateIssueCommentCollectionFromReader(IDataReader returnData)
        {
            IssueCommentCollection cmtCollection = new IssueCommentCollection();
            while (returnData.Read())
            {
                IssueComment newComment = new IssueComment(IntegerType.FromObject(returnData["CommentId"]), IntegerType.FromObject(returnData["IssueId"]), StringType.FromObject(returnData["Comment"]), StringType.FromObject(returnData["CreatorUsername"]), StringType.FromObject(returnData["CreatorDisplayName"]), DateType.FromObject(returnData["DateCreated"]));
                cmtCollection.Add(newComment);
            }
            return cmtCollection;
        }

        protected CollectionBase GenerateIssueHistoryCollectionFromReader(IDataReader returnData)
        {
            IssueHistoryCollection hstCollection = new IssueHistoryCollection();
            while (returnData.Read())
            {
                IssueHistory newHistory = new IssueHistory(IntegerType.FromObject(returnData["HistoryId"]), IntegerType.FromObject(returnData["IssueId"]), StringType.FromObject(returnData["CreatorDisplayName"]), DateType.FromObject(returnData["DateCreated"]));
                hstCollection.Add(newHistory);
            }
            return hstCollection;
        }

        protected CollectionBase GenerateIssueNotificationCollectionFromReader(IDataReader returnData)
        {
            IssueNotificationCollection notCollection = new IssueNotificationCollection();
            while (returnData.Read())
            {
                IssueNotification newNotification = new IssueNotification(IntegerType.FromObject(returnData["NotificationId"]), IntegerType.FromObject(returnData["IssueId"]), StringType.FromObject(returnData["NotificationUsername"]), StringType.FromObject(returnData["NotificationDisplayName"]), StringType.FromObject(returnData["NotificationEmail"]));
                notCollection.Add(newNotification);
            }
            return notCollection;
        }

        protected CollectionBase GenerateITUserCollectionFromReader(IDataReader returnData)
        {
            ITUserCollection userCollection = new ITUserCollection();
            while (returnData.Read())
            {
                ITUser newUser = new ITUser(IntegerType.FromObject(returnData["UserId"]), StringType.FromObject(returnData["Username"]), StringType.FromObject(returnData["RoleName"]), StringType.FromObject(returnData["Email"]), StringType.FromObject(returnData["DisplayName"]), StringType.FromObject(returnData["UserPassword"]));
                userCollection.Add(newUser);
            }
            return userCollection;
        }

        protected CollectionBase GenerateMilestoneCollectionFromReader(IDataReader returnData)
        {
            MilestoneCollection mlsCollection = new MilestoneCollection();
            while (returnData.Read())
            {
                Milestone newMilestone = new Milestone(IntegerType.FromObject(returnData["MilestoneId"]), IntegerType.FromObject(returnData["ProjectId"]), StringType.FromObject(returnData["MilestoneName"]), StringType.FromObject(returnData["MilestoneImageUrl"]));
                mlsCollection.Add(newMilestone);
            }
            return mlsCollection;
        }

        protected CollectionBase GeneratePriorityCollectionFromReader(IDataReader returnData)
        {
            PriorityCollection mlsCollection = new PriorityCollection();
            while (returnData.Read())
            {
                Priority newPriority = new Priority(IntegerType.FromObject(returnData["PriorityId"]), IntegerType.FromObject(returnData["ProjectId"]), StringType.FromObject(returnData["PriorityName"]), StringType.FromObject(returnData["PriorityImageUrl"]));
                mlsCollection.Add(newPriority);
            }
            return mlsCollection;
        }

        protected CollectionBase GenerateProjectCollectionFromReader(IDataReader returnData)
        {
            ProjectCollection prjCollection = new ProjectCollection();
            while (returnData.Read())
            {
                Project prj = new Project(IntegerType.FromObject(returnData["ProjectId"]), StringType.FromObject(returnData["ProjectName"]), StringType.FromObject(returnData["ProjectDescription"]), StringType.FromObject(returnData["ProjectManagerDisplayName"]), StringType.FromObject(returnData["ProjectCreatorDisplayName"]), DateType.FromObject(returnData["ProjectCreationDate"]));
                prjCollection.Add(prj);
            }
            return prjCollection;
        }

        protected CollectionBase GenerateQueryClauseCollectionFromReader(IDataReader returnData)
        {
            QueryClauseCollection queryCollection = new QueryClauseCollection();
            while (returnData.Read())
            {
                QueryClause newQueryClause = new QueryClause(StringType.FromObject(returnData["BooleanOperator"]), StringType.FromObject(returnData["FieldName"]), StringType.FromObject(returnData["ComparisonOperator"]), StringType.FromObject(returnData["FieldValue"]), (SqlDbType) IntegerType.FromObject(returnData["DataType"]));
                queryCollection.Add(newQueryClause);
            }
            return queryCollection;
        }

        protected CollectionBase GenerateQueryCollectionFromReader(IDataReader returnData)
        {
            QueryCollection qCollection = new QueryCollection();
            while (returnData.Read())
            {
                Query newQuery = new Query(IntegerType.FromObject(returnData["QueryId"]), StringType.FromObject(returnData["QueryName"]));
                qCollection.Add(newQuery);
            }
            return qCollection;
        }

        protected CollectionBase GenerateRelatedIssueCollectionFromReader(IDataReader returnData)
        {
            RelatedIssueCollection issCollection = new RelatedIssueCollection();
            while (returnData.Read())
            {
                RelatedIssue newIssue = new RelatedIssue(IntegerType.FromObject(returnData["IssueId"]), StringType.FromObject(returnData["IssueTitle"]), DateType.FromObject(returnData["DateCreated"]));
                issCollection.Add(newIssue);
            }
            return issCollection;
        }

        protected CollectionBase GenerateRoleCollectionFromReader(IDataReader returnData)
        {
            RoleCollection colRoles = new RoleCollection();
            while (returnData.Read())
            {
                Role newRole = new Role(IntegerType.FromObject(returnData["RoleId"]), StringType.FromObject(returnData["RoleName"]));
                colRoles.Add(newRole);
            }
            return colRoles;
        }

        protected CollectionBase GenerateStatusCollectionFromReader(IDataReader returnData)
        {
            StatusCollection stsCollection = new StatusCollection();
            while (returnData.Read())
            {
                Status newStatus = new Status(IntegerType.FromObject(returnData["StatusId"]), IntegerType.FromObject(returnData["ProjectId"]), StringType.FromObject(returnData["StatusName"]), StringType.FromObject(returnData["StatusImageUrl"]));
                stsCollection.Add(newStatus);
            }
            return stsCollection;
        }

        public abstract ProjectCollection GetAllProjects();
        public abstract RoleCollection GetAllRoles();
        public abstract ITUserCollection GetAllUsers();
        public abstract ITUserCollection GetAllUsersByRoleName(string roleName);
        public abstract CategoryCollection GetCategoriesByProjectId(int projectId);
        public abstract RelatedIssueCollection GetChildIssues(int issueId);
        public abstract CustomFieldCollection GetCustomFieldsByIssueId(int issueId);
        public abstract CustomFieldCollection GetCustomFieldsByIssueId_2(int issueId);
        public abstract CustomFieldCollection GetCustomFieldsByProjectId(int projectId);
        public abstract IssueAttachment GetIssueAttachmentById(int attachmentId);
        public abstract IssueAttachmentCollection GetIssueAttachmentsByIssueId(int issueId);
        public abstract Issue GetIssueById(int issueId);
        public abstract IssueCommentCollection GetIssueCommentsByIssueId(int issueId);
        public abstract IssueHistoryCollection GetIssueHistoryByIssueId(int issueId);
        public abstract IssueNotificationCollection GetIssueNotificationsByIssueId(int issueId);
        public abstract IssueCollection GetIssuesByAssignedUsername(int projectId, string AssignedUsername);
        public abstract IssueCollection GetIssuesByCreatorUsername(int projectId, string creatorUsername);
        public abstract IssueCollection GetIssuesByOwnerUsername(int projectId, string creatorUsername);
        public abstract IssueCollection GetIssuesByProjectId(int projectId);
        public abstract IssueCollection GetIssuesByRelevancy(int projectId, string username);
        public abstract MilestoneCollection GetMilestoneByProjectId(int milestoneId);
        public abstract RelatedIssueCollection GetParentIssues(int issueId);
        public abstract PriorityCollection GetPrioritiesByProjectId(int projectId);
        public abstract Project GetProjectById(int projectId);
        public abstract ProjectCollection GetProjectByMemberUsername(string username);
        public abstract QueryCollection GetQueriesByUsername(string username, int projectId);
        public abstract RelatedIssueCollection GetRelatedIssues(int issueId);
        public abstract StatusCollection GetStatusByProjectId(int projectId);
        public abstract ITUser GetUserById(int userId);
        public abstract ITUser GetUserByUsername(string username);
        public abstract ITUserCollection GetUsersByProjectId(int projectId);
        public abstract IssueCollection PerformQuery(int projectId, QueryClauseCollection queryClauses);
        public abstract IssueCollection PerformSavedQuery(int projectId, int queryId);
        public abstract bool RemoveUserFromProject(int userId, int projectId);
        public abstract bool SaveCustomFieldValues(int issueId, CustomFieldCollection fields);
        public abstract bool SaveQuery(string username, int projectId, string queryName, QueryClauseCollection queryClauses);
        public abstract bool SaveSingleCustomFieldValues(int issueId, string field);
        public abstract bool UpdateCustomField(CustomField customFieldToUpdate);
        public abstract bool UpdateIssue(Issue issueToUpdate);
        public abstract bool UpdateProject(Project projectToUpdate);
        public abstract bool UpdateUser(ITUser user);

        public string ConnectionString
        {
            get
            {
                string str = ConfigurationSettings.AppSettings["ConnectionString"];
                if ((str == null) || (str.Length <= 0))
                {
                    throw new ApplicationException("ConnectionString configuration is missing from you web.config. It should contain  <appSettings><add key=\"ConnectionString\" value=\"database=IssueTrackerStarterKit;server=localhost;Trusted_Connection=true\" /></appSettings> ");
                }
                return str;
            }
            set
            {
                this._connectionString = value;
            }
        }

        public abstract bool SupportsProjectCloning { get; }

        public delegate CollectionBase GenerateCollectionFromReader(IDataReader returnData);
    }
}

